package com.lv.suyiyong.hfrbusines

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Intent
import android.os.Bundle
import androidx.multidex.MultiDex
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.LogUtils
import com.lv.common.YgxManager
import com.lv.common.base.BaseApplication
import com.lv.common.im.GenerateTestUserSig
import com.lv.common.im.push.OfflineMessageDispatcher
import com.lv.common.im.push.OfflinePushAPIDemo
import com.lv.common.im.push.OfflinePushConfigs
import com.lv.common.im.push.OfflinePushLocalReceiver
import com.lv.common.ktx.application
import com.lv.common.thirdparty.ShareUtils
import com.lv.common.utils.ARoutUtils
import com.lv.common.utils.Constants
import com.lv.common.utils.showToast
import com.lv.service.moduleService
import com.lv.service.repo.UserDbHelper
import com.lv.suyiyong.hfrbusines.net.moduleMain
import com.lv.suyiyong.hfrbusines.ui.HomeActivity
import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMValueCallback
import com.tencent.qcloud.tim.tuiofflinepush.utils.BrandUtil
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.interfaces.TUICallback
import com.tencent.qcloud.tuicore.interfaces.TUILoginListener
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter
import com.tencent.qcloud.tuikit.timcommon.util.TUIUtil
import com.tencent.qcloud.tuikit.tuichat.config.TUIChatConfigs
import com.ygx.zxing.model.moduleZxing
import org.json.JSONException
import org.json.JSONObject
import org.koin.core.context.loadKoinModules
import org.koin.core.module.Module
import java.util.LinkedList
import kotlin.system.exitProcess


/**
 * 作者： ygx
 * 日期： 2020年04月27日 14:51
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 *      _              _           _     _   ____  _             _ _
 *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/  -- 志威 zhiwei.org
 *
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * Application的声明类
 */
class YgxApplication : BaseApplication() {
    private var offlinePushAPIDemo: OfflinePushAPIDemo? = null
    private var offlinePushLocalReceiver: OfflinePushLocalReceiver? = null
    private val modules = arrayListOf<Module>(
        moduleService, moduleMain, moduleZxing,
    )

    override fun initConfig() {
        super.initConfig()
        if (isMainProcess()) {
            registerActivityLifecycleCallbacks(StatisticActivityLifecycleCallback())
            initLoginStatusListener()
            TUIChatConfigs.getGeneralConfig().isEnableMultiDeviceForCall = true
            initOfflinePushConfigs()
        }
        MultiDex.install(this)

        //doKit的初始化配置
//        AssistantApp.initConfig(application)
        //打印开关
        LogUtils.getConfig().isLogSwitch = true
        loadKoinModules(modules)
//        ARouter.openDebug()
        ARouter.init(application)
        YgxManager.initialize(application)
        ShareUtils.get().initShare(
            application,
            Constants.WXAPP_ID,
//            Constants.QQ_ID
        )

//        // 1. 从即时通信 IM 控制台获取应用 SDKAppID。
// 2. 初始化 config 对象。
//        val config = V2TIMSDKConfig()
//// 3. 指定 log 输出级别。
//        config.logLevel = V2TIMSDKConfig.V2TIM_LOG_INFO
//// 4. 添加 V2TIMSDKListener 的事件监听器，sdkListener 是 V2TIMSDKListener 的实现类，如果您不需要监听 IM SDK 的事件，这个步骤可以忽略。
//        V2TIMManager.getInstance()
//            .initSDK(this, GenerateTestUserSig.SDKAPPID, config)
    }

    private fun isMainProcess(): Boolean {
        val am = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager
        val mainProcessName = this.packageName
        val currentProcessName = TUIUtil.getProcessName()
        return mainProcessName == currentProcessName
    }

    private var sdkAppId: Int = GenerateTestUserSig.SDKAPPID

    fun init(imsdkAppId: Int) {
        initBuildInformation()
        sdkAppId = if (imsdkAppId != 0) {
            imsdkAppId
        } else {
            GenerateTestUserSig.SDKAPPID
        }
    }

    fun getSdkAppId(): Int {
        return sdkAppId
    }

    private fun initBuildInformation() {
        try {
            val buildInfoJson = JSONObject()
            buildInfoJson.put("buildBrand", BrandUtil.getBuildBrand())
            buildInfoJson.put("buildManufacturer", BrandUtil.getBuildManufacturer())
            buildInfoJson.put("buildModel", BrandUtil.getBuildModel())
            buildInfoJson.put("buildVersionRelease", BrandUtil.getBuildVersionRelease())
            buildInfoJson.put("buildVersionSDKInt", BrandUtil.getBuildVersionSDKInt())
            // 工信部要求 app 在运行期间只能获取一次设备信息。因此 app 获取设备信息设置给 SDK 后，SDK 使用该值并且不再调用系统接口。
            // The Ministry of Industry and Information Technology requires the app to obtain device information only once
            // during its operation. Therefore, after the app obtains the device information and sets it to the SDK, the SDK
            // uses this value and no longer calls the system interface.
            V2TIMManager.getInstance().callExperimentalAPI(
                "setBuildInfo",
                buildInfoJson.toString(),
                object : V2TIMValueCallback<Any?> {
                    override fun onSuccess(o: Any?) {
                        LogUtils.e(
                            "setBuildInfo success"
                        )
                    }

                    override fun onError(code: Int, desc: String) {
                        LogUtils.e(
                            "setBuildInfo code:$code desc:" + ErrorMessageConverter.convertIMError(
                                code,
                                desc
                            )
                        )
                    }
                })
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

    fun initLoginStatusListener() {
        TUILogin.addLoginListener(loginStatusListener)
    }

    private val loginStatusListener: TUILoginListener = object : TUILoginListener() {
        override fun onKickedOffline() {
            showToast("您的账号已在其它终端登录")
            logout()
        }

        override fun onUserSigExpired() {
            showToast("账号已过期，请重新登录")
            TUILogin.logout(object : TUICallback() {
                override fun onSuccess() {
                    logout()
                }

                override fun onError(errorCode: Int, errorMessage: String) {
                    logout()
                }
            })
        }
    }

    fun logout() {
        LogUtils.e("logout")
        UserDbHelper.deleteUserInfo(this)
        ARouter.getInstance().build(ARoutUtils.LoginActivityURL).navigation()
        OfflineMessageDispatcher.updateBadge(this, 0)

    }

    fun registerPushManually() {
        val registerMode: Int = OfflinePushConfigs.getOfflinePushConfigs().registerPushMode
        LogUtils.e(
            "OfflinePush register mode:$registerMode"
        )
        if (registerMode == OfflinePushConfigs.REGISTER_PUSH_MODE_AUTO) {
            return
        }
        if (offlinePushAPIDemo == null) {
            offlinePushAPIDemo = OfflinePushAPIDemo()
        }
        offlinePushAPIDemo?.registerPush(_context)
    }

    private fun initOfflinePushConfigs() {
        val sharedPreferences = getSharedPreferences("TUIKIT_DEMO_SETTINGS", MODE_PRIVATE)
        val registerMode = sharedPreferences.getInt("test_OfflinePushRegisterMode_v2", 1)
        val callbackMode = sharedPreferences.getInt("test_OfflinePushCallbackMode_v2", 1)
        LogUtils.e(
            "initOfflinePushConfigs registerMode = $registerMode"
        )
        LogUtils.e(
            "initOfflinePushConfigs callbackMode = $callbackMode"
        )
        OfflinePushConfigs.getOfflinePushConfigs().registerPushMode = registerMode
        OfflinePushConfigs.getOfflinePushConfigs().clickNotificationCallbackMode = callbackMode
        registerNotify()
    }

    // call in Application onCreate
    private fun registerNotify() {
        if (offlinePushAPIDemo == null) {
            offlinePushAPIDemo = OfflinePushAPIDemo()
        }
        val callbackMode = OfflinePushConfigs.getOfflinePushConfigs().clickNotificationCallbackMode
        LogUtils.e(
            "OfflinePush callback mode:$callbackMode"
        )
        when (callbackMode) {
            OfflinePushConfigs.CLICK_NOTIFICATION_CALLBACK_NOTIFY ->                 // 1 TUICore NotifyEvent
                offlinePushAPIDemo?.registerNotifyEvent()

            OfflinePushConfigs.CLICK_NOTIFICATION_CALLBACK_BROADCAST -> {
                // 2 broadcast
                if (offlinePushLocalReceiver == null) {
                    offlinePushLocalReceiver = OfflinePushLocalReceiver()
                }
                offlinePushAPIDemo?.registerNotificationReceiver(
                    this,
                    offlinePushLocalReceiver
                )
            }

            else -> {}
        }
    }

    //所有活动集合
    private var activityLinkedList = LinkedList<Activity>()

    /**
     * 将所有类退出栈
     */
    fun exit() {
        try {
            for (i in activityLinkedList.indices) {
                activityLinkedList[i].finish()
            }
        } catch (e: Exception) {
            e.printStackTrace()
            exitProcess(0)
        }
    }

    companion object {
        @SuppressLint("StaticFieldLeak")
        private var instances: YgxApplication? = null

        fun getInstance(): YgxApplication {
            if (instances == null) {
                synchronized(YgxApplication::class.java) {
                    if (instances == null) {
                        instances = YgxApplication()
                    }
                }
            }
            return instances!!
        }
    }

    internal class StatisticActivityLifecycleCallback : ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
            LogUtils.e(
                "onActivityCreated bundle: $bundle"
            )
            if (bundle != null) {
                // restart app
                val intent = Intent(activity, HomeActivity::class.java)
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                activity.startActivity(intent)
            }
        }

        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {}
        override fun onActivityPaused(activity: Activity) {}
        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {}
    }
}